﻿/*See 'NOTICE.txt' for license */
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using UndoRedoFramework.Core;

namespace UndoRedoFramework.Prototype
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public MainWindowViewModel()
        {
            this._context = new UndoRedoContext();
            this.UndoCommand = this._context.GetUndoCommand();
            this.RedoCommand = this._context.GetRedoCommand();

            this._sliderText = new UndoableProperty<double>(this, "SliderText", this._context, 0);

            this._sliderText2 = new UndoableProperty<double>(this, "SliderText2", this._context, 5);

            this._arbitraryText = new UndoableProperty<string>(this,"ArbitraryText",this._context,"Sanjay");

            this.TypeCharacterCommand = new UndoableDelegateCommand<string, char>(
                TypeCharacterCommand_Execute,
                TypeCharacterCommand_CanExecute, 
                TypeCharacterCommand_Undo, 
                TypeCharacterCommand_Redo, 
                "TypeCharacter", 
                this._context);

            this.BackspaceCommand = new UndoableDelegateCommand<char>(
                BackspaceCommand_Execute,
                BackspaceCommand_CanExecute,
                BackspaceCommand_Undo,
                BackspaceCommand_Redo,
                "BackspaceCommand",
                this._context);

            
        }

        #region Undo/Redo
        private UndoRedoContext _context;
        public ICommand UndoCommand { get; set; }
        public ICommand RedoCommand { get; set; }
        #endregion

        #region Properties
        #region Undoable Properties
        private UndoableProperty<double> _sliderText;
        public double SliderText
        {
            get { return _sliderText.GetValue(); }
            set { _sliderText.SetValue(value); }
        }

        private UndoableProperty<double> _sliderText2;
        public double SliderText2
        {
            get { return _sliderText2.GetValue(); }
            set { _sliderText2.SetValue(value); }
        }

		private UndoableProperty<string> _arbitraryText;
        public string ArbitraryText
        {
            get
            {
                return _arbitraryText.GetValue();
            }
            set
            {
                _arbitraryText.SetValue(value);
            }
        }

        #endregion

        #region Regular Properties

        private string _someText = "";
        public string SomeText
        {
            get { return _someText; }
            set
            {
                if (_someText != value)
                {
                    _someText = value;
                    this._context.RaisePropertyChanged(this, "SomeText");
                }
            }
        }

        #endregion
        #endregion
		
        #region Commands
        #region TypeCharacterCommand
        public UndoableDelegateCommand<string, char> TypeCharacterCommand { get; set; }

        public char TypeCharacterCommand_Execute(string s)
        {
            var c = s.First();
            this.SomeText += c;
            return c;
        }

        public bool TypeCharacterCommand_CanExecute(string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                return false;
            }

            var c = s.First();
            if (char.IsDigit(c))
            {
                return true;
            }

            return false;
        }

        public char TypeCharacterCommand_Undo(char data)
        {
            if (!this.SomeText.EndsWith(data.ToString()))
            {
                throw new NotImplementedException();
            }

            this.SomeText = this.SomeText.Substring(0, this.SomeText.Length - 1);

            return data;
        }

        public char TypeCharacterCommand_Redo(char data)
        {
            this.SomeText += data;
            return data;
        }

        #endregion

        #region BackspaceCommand
        public UndoableDelegateCommand<char> BackspaceCommand { get; set; }

        public char BackspaceCommand_Execute()
        {
            var c = this.SomeText.Last();

            this.SomeText = this.SomeText.Substring(0, this.SomeText.Length - 1);

            return c;
        }

        public bool BackspaceCommand_CanExecute()
        {
            if (this.SomeText.Length > 0)
            {
                return true;
            }

            return false;
        }

        public char BackspaceCommand_Undo(char c)
        {
            this.SomeText += c;

            return c;
        }

        public char BackspaceCommand_Redo(char c)
        {
            this.SomeText = this.SomeText.Substring(0, this.SomeText.Length - 1);
            return c;
        }
        #endregion
        #endregion

        #region INotifyPropertyChanged Members
        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { this._context.PropertyChanged += value; }
            remove { this._context.PropertyChanged -= value; }
        }
        #endregion


    }
}
